## 一、創(chuàng)建 vue3 項(xiàng)目
[Vite](https://so.csdn.net/so/search?q=Vite&spm=1001.2101.3001.7020)是一種新型前端構(gòu)建工具,能夠顯著提升前端開(kāi)發(fā)體驗(yàn)。
1、 在需要?jiǎng)?chuàng)建項(xiàng)目的目錄下打開(kāi) cmd,并輸入以下命令:
npm create vite@latest
2、 之后根據(jù)自己所需按照提示操作即可,這里是使用 ts 創(chuàng)建 vue3 項(xiàng)目。
3、 隨后使用 vs code 打開(kāi)項(xiàng)目執(zhí)行對(duì)應(yīng)命令即可完成項(xiàng)目的創(chuàng)建。
## 二、修改配置文件
這里我們需要注意到 `vite.config.ts` 這個(gè)配置文件,之后我們的配置都會(huì)寫在這里。
```
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
export default defineConfig({
// 基本路徑
base: './',
plugins: [
vue()
],
resolve: {
// src 別名配置
alias: {
"@": resolve(__dirname, 'src'),
},
// 使用路徑別名時(shí)想要省略的后綴名,可以自己增減
extensions: ['.js', '.json', '.ts']
},
server: {
// 端口號(hào)
port: 8080,
// 監(jiān)聽(tīng)所有地址
host: '0.0.0.0',
// 服務(wù)啟動(dòng)時(shí)是否自動(dòng)打開(kāi)瀏覽器
open: true,
// 允許跨域
cors: true,
// 自定義代理規(guī)則
proxy: {},
},
build: {
// 設(shè)置最終構(gòu)建的瀏覽器兼容目標(biāo)
target: 'es2015',
// 構(gòu)建后是否生成 source map 文件
sourcemap: false,
// chunk 大小警告的限制(以 kbs 為單位)
chunkSizeWarningLimit: 2000,
// 啟用/禁用 gzip 壓縮大小報(bào)告
reportCompressedSize: false,
},
})
```
在 ts 中,可能會(huì)提示找不到 path,可執(zhí)行以下命令安裝:pnpm install @types/node --save-dev
**別名配置**:
在 `tsconfig.json` 中加入配置
```
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"module": "ESNext",
"lib": [
"ES2020",
"DOM",
"DOM.Iterable"
],
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "preserve",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* 別名配置 */
"baseUrl": ".",
"paths": {
"@/*": [
"src/*"
],
},
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"references": [
{
"path": "./tsconfig.node.json"
}
],
}
```
之后即可通過(guò)@來(lái)代指src目錄了。
## 三、安裝 router
1、 在項(xiàng)目目錄的控制臺(tái)中輸入命令安裝 router:pnpm install vue-router@4
2、 為了方便測(cè)試,先在 src 目錄下創(chuàng)建 views 目錄,并在 views 目錄下創(chuàng)建 index.vue 和 about.vue 文件
index.vue
```
<template>
<div>
<h1>這是主頁(yè)!</h1>
<button @click="to">前往</button>
</div>
</template>
<script setup>
import { router } from '@/router';
function to() {
router.push('/about')
}
</script>
```
about.vue
```
<template>
<div>
<h1>這是關(guān)于頁(yè)!</h1>
<button @click="to">前往</button>
</div>
</template>
<script setup>
import { router } from '@/router';
function to() {
router.push('/')
}
</script>
```
3、 隨后在 src 目錄下創(chuàng)建目錄 router,并在 router 目錄下創(chuàng)建 index.ts 文件。
```
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
component: () => import("@/views/index.vue")
},
{
path: "/about",
component: () => import("@/views/about.vue")
},
];
export const router = createRouter({
history: createWebHistory(),
routes,
});
```
4、 在 `main.ts` 中引入
```
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { router } from './router/index'
createApp(App)
.use(router)
.mount('#app')
```
5、 最后修改 `App.vue` 文件
```
<script setup>
import { RouterView } from 'vue-router'
</script>
<template>
<RouterView></RouterView>
</template>
<style scoped>
</style>
```
## 四、引入 element plus
1、 引入依賴
pnpm install element-plus
2、全局引入
在 `main.ts` 中引入
```
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
createApp(App)
.use(ElementPlus)
.mount('#app')
```
## 五、添加環(huán)境變量
1、 在與 src 同級(jí)目錄下分別創(chuàng)建`.env.development` 和`.env.production` 文件
.env.development
```
VITE_USER_NODE_ENV=dev
VITE_PARAM=dev
VITE_BASE_URL="http://localhost:8081/v1/api"
```
.env.production
```
VITE_USER_NODE_ENV=prod
VITE_PARAM=prod
VITE_BASE_URL='https://api.example.com/v1/api'
```
需要注意的是,`VITE_` 前綴是必須要有的,否則會(huì)獲取不到
2、使用
```
import.meta.env.變量
// 例如
import.meta.env.VITE_BASE_URL
```
## 六、引入 axios
1、引入 axios
pnpm install axios
2、封裝統(tǒng)一請(qǐng)求
在 src 目錄下新建 utils 目錄,然后在 utils 目錄下創(chuàng)建 `request.ts`
```
import axios, { InternalAxiosRequestConfig, AxiosResponse } from "axios"
import { ElMessage } from 'element-plus'
// 創(chuàng)建 axios 實(shí)例
const request = axios.create({
baseURL: import.meta.env.VITE_BASE_URL,
timeout: 10000,
headers: { "Content-Type": "application/json;charset=utf-8" },
});
// 請(qǐng)求攔截器
request.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
const token = window.sessionStorage.getItem('token')
if (token) {
config.headers.Authorization = `Bearer ${token}`
}
return config
},
(error: any) => {
return Promise.reject(error)
}
);
// 響應(yīng)攔截器
request.interceptors.response.use(
(response: AxiosResponse) => {
const data = response.data;
if (data.code === 200) {
return response.data;
}
ElMessage.error(data.msg || "系統(tǒng)出錯(cuò)");
return Promise.reject(new Error(data.msg || "Error"));
},
(error: any) => {
if (error.response.data) {
ElMessage.error(error.response.data.msg || "系統(tǒng)出錯(cuò)");
}
return Promise.reject(error.message);
}
);
// 導(dǎo)出 axios 實(shí)例
export default request;
```
4、編寫 api 請(qǐng)求
在 src 下創(chuàng)建 api 目錄,定義一個(gè) page 對(duì)象,用于接收分頁(yè)返回來(lái)的數(shù)據(jù)
page.ts
```
export interface Page<T> {
records: Array<T>,
total: number,
}
```
在 api 下創(chuàng)建 test 目錄,并創(chuàng)建 test.ts 和 types.ts 文件
test.ts
```
import request from "@/utils/request"
import { AxiosPromise } from "axios";
import { HotArticleQuery, HotArticleVo } from './types'
import { Page } from "../page";
// 入?yún)⑹荋otArticleQuery,返回體是Page<HotArticleVo>
export function getArticleApi(queryParams?: HotArticleQuery) : AxiosPromise<Page<HotArticleVo>> {
return request({
url: '/article/list',
method: 'post',
data: queryParams
})
}
```
types.ts
```
// 請(qǐng)求參數(shù)
export interface HotArticleQuery {
pageSize: number;
pageIndex: number;
searchKey: string;
}
// 返回分頁(yè)數(shù)據(jù)的具體參數(shù)
export interface HotArticleVo {
id: number;
title: string;
}
```
調(diào)用
```
<template>
<div>
<h1>這是主頁(yè)!</h1>
<el-button @click="to">前往</el-button>
<el-button @click="getArticleList">獲取</el-button>
</div>
</template>
<script setup>
import { getArticleApi } from '@/api/test/test'
import { HotArticleQuery, HotArticleVo } from '@/api/test/types'
import { Page } from '@/api/page'
import { router } from '@/router';
import { reactive, ref } from 'vue';
const query = reactive<HotArticleQuery>({
pageIndex: 1,
pageSize: 10,
searchKey: ''
})
const articleData = ref<Page<HotArticleVo>>();
function getArticleList() {
getArticleApi(query).then(res => {
articleData.value = res.data
console.log(articleData.value.records)
console.log(articleData.value.total)
})
}
function to() {
router.push('/about')
}
</script>
```
## 七、狀態(tài)管理 Pinia
1、安裝pnpm install pinia
2、在 main.ts 中引入
```
import { createPinia } from "pinia";
const pinia = createPinia();
createApp(App)
.use(pinia)
.mount('#app')
```
3、創(chuàng)建 store
在 src 目錄下創(chuàng)建 store 目錄,然后創(chuàng)建一個(gè) user.ts 用于存放用戶相關(guān)數(shù)據(jù)
```
import { defineStore } from 'pinia'
// 第一個(gè)參數(shù)是應(yīng)用程序中 store 的唯一 id
export const useUsersStore = defineStore('users', {
// 配置項(xiàng)
state: () => {
// 這里假設(shè)有一些參數(shù)
return {
uid: 1,
username: 'admin',
exp: 100
}
}
})
```
4、使用 store
```
<el-button @click="get">測(cè)試pinia</el-button>
import { useUsersStore } from '@/store/user'
function get() {
const store = useUsersStore()
console.log(store)
// 或者
const { uid, username, exp} = useUsersStore()
console.log(uid)
console.log(username)
console.log(exp)
// 修改
store.exp = 200
// 重置
store.$reset()
console.log(store)
}
```
5、getter
在 user.ts 中定義一個(gè) getters
```
import { defineStore } from 'pinia'
// 第一個(gè)參數(shù)是應(yīng)用程序中 store 的唯一 id
export const useUsersStore = defineStore('users', {
// 配置項(xiàng)
state: () => {
return {
uid: 1,
username: 'admin',
exp: 100
}
},
getters: {
// 無(wú)參
addExp: (state) => {
return state.exp + 150
},
// 帶參
addExpCustom: (state) => {
return (num: number) => state.exp + num
}
}
})
```
使用
```
console.log(store.addExp)
console.log(store.addExpCustom(180))
```
6、actions 屬性
actions 屬性類似于一個(gè)方法,我們可以在里面進(jìn)行業(yè)務(wù)操作,例如發(fā)送請(qǐng)求等
```
export const useUsersStore = defineStore('users', {
// 配置項(xiàng)
state: () => {
return {
uid: 1,
username: 'admin',
exp: 100
}
},
getters: {
addExp: (state) => {
return state.exp + 150
},
addExpCustom: (state) => {
return (num: number) => state.exp + num
}
},
actions: {
showParam(param: string) {
console.log('傳入的參數(shù)為:' + param)
}
}
})
```
使用
```
store.showParam('test')
```
微信公眾號(hào)
業(yè)務(wù)咨詢:400-9969-069(24小時(shí)服務(wù)) 028-86052918
售后熱線:028-86052836
公司地址:成都市武侯區(qū)天益街38號(hào)理想中心3棟1810